/*
 * Copyright 2009 Lukasz Wozniak
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 *
 * http://www.apache.org/licenses/LICENSE-2.0 
 *
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 */
package pl.sind.blip.entities;

import java.lang.reflect.Constructor;
import java.util.HashMap;

import org.json.JSONObject;

/**
 * Simple factory creating Statuses based on their type in JSON.
 * 
 * @author Lukasz Wozniak
 * 
 */
public class StatusFactory {

	private static final String UPDATE = "Update";
	private static final String UPDATE_TIP = "UpdateTip";
	private static final String PRIVATE_MESSAGE = "PrivateMessage";
	private static final String DIRECTED_MESSAGE = "DirectedMessage";
	private static final String NOTICE = "Notice";
	private static final String STATUS = "Status";
	private final static HashMap<String, Class<? extends Status>> types;
	static {
		types = new HashMap<String, Class<? extends Status>>();
		types.put(STATUS, Status.class);
		types.put(UPDATE, Status.class);
		types.put(UPDATE_TIP, Status.class);
		types.put(NOTICE, Notice.class);
		types.put(DIRECTED_MESSAGE, DirectMessage.class);
		types.put(PRIVATE_MESSAGE, PrivateMessage.class);
	}

	/**
	 * Reads status type from JSON and instantiates correct entity. USE only on
	 * JSON containing supported entity types!<br>
	 * <ul>
	 * <li>{@link Status}</li>
	 * <li>{@link Notice}</li>
	 * <li>{@link DirectMessage}</li>
	 * <li>{@link PrivateMessage}</li>
	 * </ul>
	 * 
	 * @param json
	 * @return {@link Status} or its subclass
	 */
	public static Status createStatus(JSONObject json) {
		String type = json.optString("type");
		if (type == null) {
			type = STATUS;
			// TODO maybe it's not necessary but I dont want to cripple library
			// when new status type gets introduced
			// System.out.println("Unknown type!! "+json);
		}else if(!types.containsKey(type)){
			throw new RuntimeException("Unsupported status type "+type);
		}
		Class<? extends Status> c = types.get(type);
		try {
			Constructor<? extends Status> cons = c
					.getConstructor(JSONObject.class);
			return cons.newInstance(json);
		} catch (Exception e) {
			// shouldnt happen EVER
			throw new RuntimeException(e);
		}
	}
}
